#include "StreamManager.h"
#include "Config.h"
#include "Logger.h"
#include <regex>
#include <sstream>
#include <cstdio>
#include <iostream>
#include <fstream>

#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#endif

// 初始化静态成员
StreamManager* StreamManager::instance = nullptr;

// 单例获取实例
StreamManager& StreamManager::getInstance() {
    if (instance == nullptr) {
        instance = new StreamManager();
    }
    return *instance;
}

// 构造函数
StreamManager::StreamManager() : streaming(false) {
    LOG_INFO("初始化StreamManager");
}

// 析构函数
StreamManager::~StreamManager() {
    stopStreaming();
}

// 解析SDP
SdpInfo StreamManager::parseSdp(const std::string& sdp) {
    LOG_INFO("解析SDP: \n" + sdp);
    
    SdpInfo info;
    
    // 默认值
    info.remote_ip = Config::getInstance().getServerIp();
    info.remote_port = 5000;
    info.ssrc = "12345678";
    info.transport = "UDP";
    info.setup = "passive";
    
    // 提取目标IP地址
    size_t c_pos = sdp.find("c=IN IP4 ");
    if (c_pos != std::string::npos) {
        info.remote_ip = sdp.substr(c_pos + 9);
        info.remote_ip = info.remote_ip.substr(0, info.remote_ip.find("\r\n"));
        LOG_INFO("提取到对端IP: " + info.remote_ip);
    } else {
        LOG_WARN("未找到对端IP，使用默认IP: " + info.remote_ip);
    }

    // 提取媒体端口
    size_t m_pos = sdp.find("m=video ");
    if (m_pos != std::string::npos) {
        std::string portStr = sdp.substr(m_pos + 8);
        info.remote_port = std::stoi(portStr.substr(0, portStr.find(" ")));
        LOG_INFO("提取到对端端口: " + std::to_string(info.remote_port));
    } else {
        LOG_WARN("未找到对端端口，使用默认端口: " + std::to_string(info.remote_port));
    }

    // 提取SSRC
    size_t y_pos = sdp.find("y=");
    if (y_pos != std::string::npos) {
        info.ssrc = sdp.substr(y_pos + 2);
        info.ssrc = info.ssrc.substr(0, info.ssrc.find("\r\n"));
        LOG_INFO("提取到SSRC: " + info.ssrc);
    } else {
        LOG_WARN("未找到SSRC，使用默认值: " + info.ssrc);
    }

    // 判断传输协议和连接模式
    if (sdp.find("TCP/RTP/AVP") != std::string::npos) {
        info.transport = "TCP";
        LOG_INFO("使用TCP传输");

        // 检查a=setup行来确定TCP连接模式
        size_t setup_pos = sdp.find("a=setup:");
        if (setup_pos != std::string::npos) {
            std::string setup_value = sdp.substr(setup_pos + 8);
            setup_value = setup_value.substr(0, setup_value.find("\r\n"));
            
            if (setup_value == "active") {
                info.setup = "passive"; // 如果对方是active，我们就是passive
            } else if (setup_value == "passive") {
                info.setup = "active"; // 如果对方是passive，我们就是active
            }
            LOG_INFO("设置连接模式: " + info.setup);
        }
    } else {
        LOG_INFO("使用UDP传输");
    }
    
    LOG_INFO("推流参数已更新: IP=" + info.remote_ip + 
                ", 端口=" + std::to_string(info.remote_port) + 
                ", 传输=" + info.transport + 
                ", 模式=" + info.setup + 
                ", SSRC=" + info.ssrc);
    
    return info;
}

// 解析SDP并设置推流参数
bool StreamManager::parseSdpAndSetParams(const std::string& sdp) {
    try {
        // 使用原有的parseSdp解析SDP
        current_sdp = parseSdp(sdp);
        LOG_INFO("SDP解析成功并设置推流参数");
        return true;
    } catch(const std::exception& e) {
        LOG_ERROR("解析SDP异常: " + std::string(e.what()));
        return false;
    }
}

// 生成SDP应答 (不带参数版本，使用当前已存储的SDP信息)
std::string StreamManager::generateSdpAnswer() {
    return generateSdpAnswer(current_sdp);
}

// 生成SDP应答
std::string StreamManager::generateSdpAnswer(const SdpInfo& sdp_info) {
    std::string public_ip = Config::getInstance().getPublicIp();
    std::string device_id = Config::getInstance().getDeviceId();
    
    std::string sdp_answer;
    sdp_answer = "v=0\r\n";
    sdp_answer += "o=" + device_id + " 0 0 IN IP4 " + public_ip + "\r\n";
    sdp_answer += "s=Play\r\n";
    sdp_answer += "c=IN IP4 " + public_ip + "\r\n";
    sdp_answer += "t=0 0\r\n";
    
    if (sdp_info.transport == "TCP") {
        if (sdp_info.setup == "active") {
            // 主动模式
            sdp_answer += "m=video 9 TCP/RTP/AVP 96 97 98 99\r\n";
            sdp_answer += "a=setup:active\r\n";
            sdp_answer += "a=connection:new\r\n";
        } else {
            // 被动模式
            sdp_answer += "m=video 5000 TCP/RTP/AVP 96 97 98 99\r\n";
            sdp_answer += "a=setup:passive\r\n";
            sdp_answer += "a=connection:new\r\n";
        }
    } else {
        // UDP模式
        sdp_answer += "m=video 5000 RTP/AVP 96 97 98 99\r\n";
    }
    
    sdp_answer += "a=sendonly\r\n";
    sdp_answer += "a=rtpmap:96 PS/90000\r\n";
    sdp_answer += "a=rtpmap:98 H264/90000\r\n";
    sdp_answer += "a=rtpmap:97 MPEG4/90000\r\n";
    sdp_answer += "a=rtpmap:99 H265/90000\r\n";
    sdp_answer += "y=" + sdp_info.ssrc + "\r\n";
    
    return sdp_answer;
}

// 开始推流 (不带参数版本，使用当前已存储的SDP信息)
bool StreamManager::startStreaming() {
    return startStreaming(current_sdp);
}

// 开始推流
bool StreamManager::startStreaming(const SdpInfo& sdp_info) {
    // 如果已经在推流，先停止
    if (streaming) {
        stopStreaming();
    }
    
    // 保存当前SDP信息
    current_sdp = sdp_info;
    
    // 设置推流标志
    streaming = true;
    
    // 启动推流线程
    LOG_INFO("启动推流线程");
    stream_thread = std::thread(&StreamManager::streamingThreadFunc, this);
    stream_thread.detach();
    
    return true;
}

// 停止推流
void StreamManager::stopStreaming() {
    if (streaming) {
        streaming = false;
        // 等待线程结束
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        LOG_INFO("推流已停止");
    }
}

// 推流线程函数
void StreamManager::streamingThreadFunc() {
    LOG_INFO("推流线程开始运行");
    
    // 等待一小段时间，确保呼叫已完全建立
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    
    // 检查测试视频文件
    std::string video_path = "test.mp4";
    std::ifstream f(video_path.c_str());
    if (!f.good()) {
        LOG_ERROR("错误: 测试视频文件 " + video_path + " 不存在!");
        // 尝试在其他位置查找
        if (access("direct_build/test.mp4", F_OK) != -1) {
            video_path = "direct_build/test.mp4";
            LOG_INFO("找到测试视频: " + video_path);
        } else {
            char current_path[FILENAME_MAX];
            if (getcwd(current_path, sizeof(current_path))) {
                LOG_INFO("当前工作目录: " + std::string(current_path));
            }
            LOG_ERROR("无法找到测试视频文件，推流将使用测试图像");
            video_path = "";
        }
    }
    
    // 构建FFmpeg命令
    std::string ffmpeg_cmd;
    
    // 如果视频文件存在，使用它作为输入源
    if (!video_path.empty()) {
        LOG_INFO("使用测试视频作为推流源: " + video_path);
        ffmpeg_cmd = "ffmpeg -re -i " + video_path + " ";
    } else {
        // 否则使用测试图像
        LOG_INFO("使用测试图像作为推流源");
        ffmpeg_cmd = "ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=25 -pix_fmt yuv420p ";
    }
    
    // 根据传输协议和连接方式构建不同的FFmpeg命令
    if (current_sdp.transport == "TCP") {
        if (current_sdp.setup == "active") {
            // TCP主动连接模式
            ffmpeg_cmd += "-codec:v h264 -profile:v main -b:v 2M -f rtp ";
            ffmpeg_cmd += "rtp://" + current_sdp.remote_ip + ":" + std::to_string(current_sdp.remote_port) + "?pkt_size=1316";
        } else {
            // TCP被动连接模式
            ffmpeg_cmd += "-codec:v h264 -profile:v main -b:v 2M -f rtp ";
            ffmpeg_cmd += "-ssrc " + current_sdp.ssrc + " ";
            ffmpeg_cmd += "rtp://" + current_sdp.remote_ip + ":" + std::to_string(current_sdp.remote_port) + "?pkt_size=1316";
        }
    } else {
        // UDP模式
        ffmpeg_cmd += "-codec:v h264 -profile:v main -b:v 2M -f rtp ";
        ffmpeg_cmd += "-ssrc " + current_sdp.ssrc + " ";
        ffmpeg_cmd += "rtp://" + current_sdp.remote_ip + ":" + std::to_string(current_sdp.remote_port) + "?pkt_size=1316";
    }
    
    LOG_INFO("执行FFmpeg命令: " + ffmpeg_cmd);
    
    // 在后台执行FFmpeg命令
    #ifdef _WIN32
    ffmpeg_cmd = "start /b " + ffmpeg_cmd + " > nul 2>&1";
    #else
    ffmpeg_cmd += " > /dev/null 2>&1 &";
    #endif
    
    // 执行FFmpeg命令
    int ret = system(ffmpeg_cmd.c_str());
    if (ret != 0) {
        LOG_ERROR("执行FFmpeg命令失败，返回码: " + std::to_string(ret));
    }
    
    // 持续监控streaming标志
    while (streaming) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    // 停止FFmpeg进程
    #ifdef _WIN32
    system("taskkill /F /IM ffmpeg.exe > nul 2>&1");
    #else
    system("pkill -f ffmpeg > /dev/null 2>&1");
    #endif
    
    LOG_INFO("推流线程退出");
}

// 测试SDP解析方法
void StreamManager::testSdpParsing(const std::string& sdp) {
    try {
        LOG_INFO("执行SDP解析测试");
        SdpInfo info = parseSdp(sdp);
        LOG_INFO("SDP解析测试成功");
        LOG_INFO("解析结果: IP=" + info.remote_ip + 
                    ", 端口=" + std::to_string(info.remote_port) + 
                    ", SSRC=" + info.ssrc + 
                    ", 传输=" + info.transport + 
                    ", 模式=" + info.setup);
                    
        // 测试生成SDP应答
        std::string answer = generateSdpAnswer(info);
        LOG_INFO("生成SDP应答:\n" + answer);
    } catch(const std::exception& e) {
        LOG_ERROR("SDP解析测试失败: " + std::string(e.what()));
    }
} 